package com.yekaile.carsystem.service;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yekaile.carsystem.controller.vo.MenuVO;
import com.yekaile.carsystem.controller.vo.RoleAuthorityVO;
import com.yekaile.carsystem.controller.vo.RoleVO;
import com.yekaile.carsystem.entity.*;
import com.yekaile.carsystem.mapper.RoleAuthorityMapper;
import com.yekaile.carsystem.mapper.RoleMapper;
import com.yekaile.carsystem.mapper.SystemAuthorityMapper;
import com.yekaile.carsystem.mapper.UserMapper;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author yekaile
 */
@Service
@AllArgsConstructor(onConstructor_ = @Autowired)
public class RoleServiceImpl implements RoleService {


    RoleMapper roleMapper;

    SystemAuthorityMapper systemAuthorityMapper;

    RoleAuthorityMapper roleAuthorityMapper;

    UserMapper userMapper;

    UserServiceImpl userService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addRole(RoleAuthorityVO roleAuthorityVO) {
        Role role = new Role();
        role.setDescription(roleAuthorityVO.getDescription());
        role.setRoleName(roleAuthorityVO.getRoleName());
        role.setGmtCreated(DateUtil.now());
        role.setGmtModified(DateUtil.now());
        roleMapper.insertSelective(role);
        SystemAuthorityExample example = new SystemAuthorityExample();
        SystemAuthorityExample.Criteria criteria = example.createCriteria();
        criteria.andDescriptionIn(roleAuthorityVO.getDescriptions());
        List<SystemAuthority> authorities = systemAuthorityMapper.selectByExample(example);
        List<RoleAuthority> roleAuthorities = new ArrayList<>();
        authorities.forEach(authority -> {
            RoleAuthority roleAuthority = new RoleAuthority();
            roleAuthority.setRoleId(role.getRoleId());
            roleAuthority.setSystemAuthorityId(authority.getSystemAuthorityId());
            roleAuthority.setGmtCreated(DateUtil.now());
            roleAuthority.setGmtModified(DateUtil.now());
            roleAuthorities.add(roleAuthority);
            roleAuthority.setIsDeleted(0);
        });

        return roleAuthorityMapper.batchInsert(roleAuthorities);
    }

    @Override
    public int deleteRole(Integer roleId) {
        Role role = roleMapper.selectByPrimaryKey(roleId);
        role.setIsDeleted(1);
        return roleMapper.updateByPrimaryKeySelective(role);
    }

    @Override
    public List<Role> getOnlyAllRoles() {
        return roleMapper.selectAll();
    }

    @Override
    public PageInfo<RoleVO> getAllRoles(Integer pageNum, Integer pageSize) {
        Page<RoleVO> page = PageHelper.startPage(pageNum, pageSize);
        List<Role> roles = roleMapper.selectAll();
        List<RoleVO> roleVOS = new ArrayList<>();
        roles.forEach(role -> {
            Set<SystemAuthority> authorities = new HashSet<>(userMapper.selectAuthoritiesByRole(role.getRoleId()));
            Set<MenuVO> menuVOS = userService.getAuthorityOne(authorities);
            roleVOS.add(new RoleVO(role, menuVOS));
        });
        PageInfo<RoleVO> pageInfo = new PageInfo<>(roleVOS);
        System.out.println(JSON.toJSONString(pageInfo));
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateRole(RoleAuthorityVO roleAuthorityVO) {
        RoleExample example = new RoleExample();
        RoleExample.Criteria criteria = example.createCriteria();
        criteria.andDescriptionEqualTo(roleAuthorityVO.getDescription());
        criteria.andRoleNameEqualTo(roleAuthorityVO.getRoleName());
        Role role = roleMapper.selectByExample(example).get(0);
        //获取该角色所有的权限
        SystemAuthorityExample systemAuthorityExample = new SystemAuthorityExample();
        SystemAuthorityExample.Criteria criteria1 = systemAuthorityExample.createCriteria();
        criteria1.andDescriptionIn(roleAuthorityVO.getDescriptions());
        //获取该权限描述对应的所有权限
        Set<SystemAuthority> authorities1 = new HashSet<>(systemAuthorityMapper.selectByExample(systemAuthorityExample));
        RoleAuthorityExample roleAuthorityExample = new RoleAuthorityExample();
        RoleAuthorityExample.Criteria criteria2 = roleAuthorityExample.createCriteria();
        criteria2.andRoleIdEqualTo(role.getRoleId());
        roleAuthorityMapper.deleteByExample(roleAuthorityExample);
        List<RoleAuthority> roleAuthorities = new ArrayList<>();
        authorities1.forEach(authority -> {
            RoleAuthority roleAuthority = new RoleAuthority();
            roleAuthority.setGmtCreated(DateUtil.now());
            roleAuthority.setGmtModified(DateUtil.now());
            roleAuthority.setRoleId(role.getRoleId());
            roleAuthority.setSystemAuthorityId(authority.getSystemAuthorityId());
            roleAuthority.setIsDeleted(0);
            roleAuthorities.add(roleAuthority);
        });
        return roleAuthorityMapper.batchInsert(roleAuthorities);
    }

    @Override
    public RoleVO getRole(Integer roleId) {
        Role role = roleMapper.selectByPrimaryKey(roleId);
        Set<SystemAuthority> authorities = new HashSet<>(userMapper.selectAuthoritiesByRole(role.getRoleId()));
        Set<MenuVO> menuVOS = userService.getAuthorityOne(authorities);
        return new RoleVO(role, menuVOS);
    }
}
